﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using LumiSoft.Net.AUTH;
using LumiSoft.Net.Mail;
using LumiSoft.Net.MIME;
using LumiSoft.Net.POP3.Client;
using LumiSoft.Net.SMTP.Client;

namespace CYTS.Aoyou.Framework.Utility
{
    /// <summary>
    /// 邮件发送帮助类
    /// </summary>
    public class SmtpHelper
    {
        /// <summary>
        /// 验证邮件格式
        /// </summary>
        /// <param name="inputEmail"></param>
        /// <returns></returns>
        public static bool IsEmail(string inputEmail)
        {
            string strRegex = @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
            Regex re = new Regex(strRegex);
            if (re.IsMatch(inputEmail))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="from">发件人的电子邮件地址</param>
        /// <param name="to">以逗号分隔的收件人电子邮件地址列表</param>
        /// <param name="cc">以逗号分隔的抄送电子邮件地址列表</param>
        /// <param name="bcc">以逗号分隔的密抄电子邮件地址列表</param>
        /// <param name="subject">邮件标题</param>
        /// <param name="body">邮件内容</param>
        /// <returns>邮件唯一标识</returns>
        public static string SendMessage(string from, string to, string cc, string bcc, string subject, string body)
        {
            Dictionary<string, string> toMails = new Dictionary<string, string>();
            foreach (string address in to.Split(',').ToList())
            {
                toMails.Add(address, address);
            }

            Dictionary<string, string> ccMails = new Dictionary<string, string>();
            foreach (string address in cc.Split(',').ToList())
            {
                ccMails.Add(address, address);
            }

            Dictionary<string, string> bccMails = new Dictionary<string, string>();
            foreach (string address in bcc.Split(',').ToList())
            {
                bccMails.Add(address, address);
            }

            Mail_Message m = Create_PlainText_Html_Attachment_Image(from, from, toMails, ccMails, bccMails, subject, body, new Dictionary<string, string>());

            string messageID = Send(m);
            return messageID;
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="from">发件人的电子邮件地址</param>
        /// <param name="to">以逗号分隔的收件人电子邮件地址列表</param>
        /// <param name="cc">以逗号分隔的抄送电子邮件地址列表</param>
        /// <param name="bcc">以逗号分隔的密抄电子邮件地址列表</param>
        /// <param name="subject">邮件标题</param>
        /// <param name="body">邮件内容</param>
        /// <param name="attachments">附件列表（key：附件地址，value：附件名称）</param>
        /// <returns>邮件唯一标识</returns>
        public static string SendMessage(string from, string to, string cc, string bcc, string subject, string body, Dictionary<string, string> attachments)
        {
            Dictionary<string, string> toMails = new Dictionary<string, string>();
            foreach (string address in to.Split(',').ToList())
            {
                toMails.Add(address, address);
            }

            Dictionary<string, string> ccMails = new Dictionary<string, string>();
            foreach (string address in cc.Split(',').ToList())
            {
                ccMails.Add(address, address);
            }

            Dictionary<string, string> bccMails = new Dictionary<string, string>();
            foreach (string address in bcc.Split(',').ToList())
            {
                bccMails.Add(address, address);
            }

            Mail_Message m = Create_PlainText_Html_Attachment_Image(from, from, toMails, ccMails, bccMails, subject, body, attachments);

            string messageID = Send(m);
            return messageID;
        }

        public static string SendMessage(string from, string fromDisplay, Dictionary<string, string> toList, Dictionary<string, string> ccList, Dictionary<string, string> bccList, string subject, string body, Dictionary<string, string> attachments)
        {
            Mail_Message m = Create_PlainText_Html_Attachment_Image(from, fromDisplay, toList, ccList, bccList, subject, body, attachments);

            string messageID = Send(m);
            return messageID;
        }

        public static string SendMessage(string from, string fromDisplay, Dictionary<string, string> toList, Dictionary<string, string> ccList, Dictionary<string, string> bccList, 
            string subject, string body, Dictionary<string, string> attachments, string notifyEmail, string plaintTextTips)
        {
            Mail_Message m = Create_PlainText_Html_Attachment_Image(from, fromDisplay, toList, ccList, bccList, subject, body, attachments, notifyEmail, plaintTextTips);

            string messageID = Send(m);
            return messageID;
        }

        private static string Send(Mail_Message m)
        {
            using (SMTP_Client smtp = new SMTP_Client())
            {
                smtp.Connect("cyts-mail.cytsonline.com", 25, false);
                smtp.EhloHelo("cyts-mail.cytsonline.com");
                smtp.Authenticate("e-service", "1q2w3e4r5t");
                //AUTH_SASL_Client_Plain authhh = new AUTH_SASL_Client_Plain("e-service", "1q2w3e4r5t");
                //smtp.Auth(authhh);

                smtp.MailFrom(m.From[0].Address, -1);
                for (int i = 0; i < m.To.Count; i++ )
                {
                    smtp.RcptTo(((Mail_t_Mailbox)m.To[i]).Address);
                }

                using (MemoryStream stream = new MemoryStream())
                {
                    m.ToStream(stream, new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q, Encoding.UTF8), Encoding.UTF8);
                    stream.Position = 0;
                    smtp.SendMessage(stream);
                }

                string messageID = String.Empty;
                if (m != null)
                {
                    messageID = m.MessageID;
                    m.Dispose();
                }

                smtp.Disconnect();

                return messageID;
            }
        }

        private static Mail_Message Create_PlainText_Html_Attachment_Image(string mailFrom, string mailFromDisplay, Dictionary<string, string> toMails, Dictionary<string, string> ccMails, Dictionary<string, string> bccMails,
            string subject, string body, Dictionary<string, string> attachments, string notifyEmail = "", string plaintTextTips = "")
        {
            Mail_Message msg = new Mail_Message();
            msg.MimeVersion = "1.0";
            msg.MessageID = MIME_Utils.CreateMessageID(); //生成邮件唯一标识
            msg.Date = DateTime.Now; //发送时间
            msg.Subject = subject; //主题

            //发件人
            msg.From = new Mail_t_MailboxList();
            msg.From.Add(new Mail_t_Mailbox(mailFromDisplay, mailFrom));

            //收件人
            msg.To = new Mail_t_AddressList();
            foreach (string address in toMails.Keys)
            {
                string displayName = toMails[address];
                msg.To.Add(new Mail_t_Mailbox(displayName, address));
            }

            //抄送
            msg.Cc = new Mail_t_AddressList();
            foreach (string address in ccMails.Keys)
            {
                string displayName = ccMails[address];
                msg.Cc.Add(new Mail_t_Mailbox(displayName, address));
            }

            //密件抄送
            msg.Bcc = new Mail_t_AddressList();
            foreach (string address in bccMails.Keys)
            {
                string displayName = bccMails[address];
                msg.Bcc.Add(new Mail_t_Mailbox(displayName, address));
            }

            //设置回执通知
            if (!string.IsNullOrEmpty(notifyEmail) && IsEmail(notifyEmail))
            {
                msg.DispositionNotificationTo.Add(new Mail_t_Mailbox(notifyEmail, notifyEmail));
            }

            #region MyRegion
            //--- multipart/mixed -----------------------------------
            MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed);
            contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.');
            MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed);
            msg.Body = multipartMixed;

            //--- multipart/alternative -----------------------------
            MIME_Entity entity_multipartAlternative = new MIME_Entity();
            MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative);
            contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.');
            MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative);
            entity_multipartAlternative.Body = multipartAlternative;
            multipartMixed.BodyParts.Add(entity_multipartAlternative);

            //--- text/plain ----------------------------------------
            MIME_Entity entity_text_plain = new MIME_Entity();
            MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain);
            entity_text_plain.Body = text_plain;

            //普通文本邮件内容，如果对方的收件客户端不支持HTML，这是必需的
            string plainTextBody = "如果你邮件客户端不支持HTML格式，或者你切换到“普通文本”视图，将看到此内容";
            if (!string.IsNullOrEmpty(plaintTextTips))
            {
                plainTextBody = plaintTextTips;
            }
            text_plain.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, plainTextBody);
            multipartAlternative.BodyParts.Add(entity_text_plain);

            //--- text/html -----------------------------------------
            string htmlText = body;//"<html>这是一份测试邮件，<img src=\"cid:test.jpg\">来自<font color=red><b>LumiSoft.Net</b></font></html>";
            MIME_Entity entity_text_html = new MIME_Entity();
            MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html);
            entity_text_html.Body = text_html;
            text_html.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, htmlText);
            multipartAlternative.BodyParts.Add(entity_text_html);

            //--- application/octet-stream -------------------------
            WebClient client = new WebClient();
            foreach (string attach in attachments.Keys)
            {
                try
                {
                    byte[] bytes = client.DownloadData(attach);
                    using (MemoryStream stream = new MemoryStream(bytes))
                    {
                        multipartMixed.BodyParts.Add(Mail_Message.CreateAttachment(stream, attachments[attach]));
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                    //LogTextHelper.Error(ex);
                }
            }
            #endregion
            return msg;
        }
    }

    /// <summary>
    /// 邮件接收帮助类
    /// </summary>
    public class Pop3Helper
    {
        //需要首先设置这些信息
        string pop3Server;
        int pop3Port;
        string userName, password;

        public Pop3Helper(string userName, string password)
            : this("cyts-mailhub1.cytsonline.com", 110, userName, password) 
        {

        }

        public Pop3Helper(string server, int port, string userName, string password)
        {
            this.pop3Server = server;
            this.pop3Port = port;
            this.userName = userName;
            this.password = password;
        }

        public List<Mail_Message> GetAllMessage()
        {
            using (POP3_Client pop3 = new POP3_Client())
            {
                //与Pop3服务器建立连接
                pop3.Connect(pop3Server, pop3Port);
                //验证身份
                pop3.Login(userName, password);

                //获取邮件信息列表
                List<Mail_Message> emailList = new List<Mail_Message>();
                for (int i = 0; i <pop3.Messages.Count; i++)
                {
                    Mail_Message m = Mail_Message.ParseFromByte(pop3.Messages[i].MessageToByte());
                    emailList.Add(m);
                }

                //与Pop3服务器断开连接
                pop3.Disconnect();

                return emailList;
            }
        }

        public List<Mail_Message> GetMessage(List<string> filerAddress, List<string> uids)
        {
            using (POP3_Client pop3 = new POP3_Client())
            {
                //与Pop3服务器建立连接
                pop3.Connect(pop3Server, pop3Port);
                //验证身份
                pop3.Login(userName, password);

                //获取邮件信息列表
                List<Mail_Message> emailList = new List<Mail_Message>();
                for (int i = 0; i < pop3.Messages.Count; i++)
                {
                    Mail_Message m = Mail_Message.ParseFromByte(pop3.Messages[i].MessageToByte());
                    if (filerAddress.Contains(m.From[0].Address) && !uids.Contains(m.MessageID)) //过滤已读邮件
                    {
                        emailList.Add(m);
                    }
                }

                //与Pop3服务器断开连接
                pop3.Disconnect();

                return emailList;
            }
        }

        public List<Mail_Message> GetMessageBySuffix(string emailSuffix)
        {
            using (POP3_Client pop3 = new POP3_Client())
            {
                //与Pop3服务器建立连接
                pop3.Connect(pop3Server, pop3Port);
                //验证身份
                pop3.Login(userName, password);

                //获取邮件信息列表
                List<Mail_Message> emailList = new List<Mail_Message>();
                for (int i = 0; i < pop3.Messages.Count; i++)
                {
                    Mail_Message m = Mail_Message.ParseFromByte(pop3.Messages[i].MessageToByte());
                    if (m.From[0].Address.IndexOf(emailSuffix) > 0)
                    {
                        emailList.Add(m);
                    }
                }

                //与Pop3服务器断开连接
                pop3.Disconnect();

                return emailList;
            }
        }

        public Mail_Message GetMessage(int index)
        {
            using (POP3_Client pop3 = new POP3_Client())
            {
                //与Pop3服务器建立连接
                pop3.Connect(pop3Server, pop3Port);
                //验证身份
                pop3.Login(userName, password);

                //获取邮件信息列表
                Mail_Message email = new Mail_Message();
                if (pop3.Messages.Count > index + 1)
                {
                    if (pop3.Messages[index] != null)
                    {
                        email = Mail_Message.ParseFromByte(pop3.Messages[index].MessageToByte());
                    }
                }

                //与Pop3服务器断开连接
                pop3.Disconnect();

                return email;
            }
        }

        public Mail_Message GetMessage(string uid)
        {
            using (POP3_Client pop3 = new POP3_Client())
            {
                //与Pop3服务器建立连接
                pop3.Connect(pop3Server, pop3Port);
                //验证身份
                pop3.Login(userName, password);

                //获取邮件信息列表
                Mail_Message email = new Mail_Message();
                if (pop3.Messages.Count > 0)
                {
                    if (pop3.Messages[uid] != null)
                    {
                        email = Mail_Message.ParseFromByte(pop3.Messages[uid].MessageToByte());
                    }
                }

                //与Pop3服务器断开连接
                pop3.Disconnect();

                return email;
            }
        }

        public void DeleteMessage()
        {
            using (POP3_Client pop3 = new POP3_Client())
            {
                //与Pop3服务器建立连接
                pop3.Connect(pop3Server, pop3Port);
                //验证身份
                pop3.Login(userName, password);

                if (pop3.Messages.Count > 0)
                {
                    for (int i = 0; i < pop3.Messages.Count; i++)
                    {
                        pop3.Messages[i].MarkForDeletion();
                    }
                }

                //与Pop3服务器断开连接
                pop3.Disconnect();
            }
        }

        public void DeleteMessage(List<string> messageIDs)
        {
            using (POP3_Client pop3 = new POP3_Client())
            {
                //与Pop3服务器建立连接
                pop3.Connect(pop3Server, pop3Port);
                //验证身份
                pop3.Login(userName, password);

                if (pop3.Messages.Count > 0)
                {
                    for (int i = 0; i < pop3.Messages.Count; i++)
                    {
                        Mail_Message m = Mail_Message.ParseFromByte(pop3.Messages[i].MessageToByte());
                        if (messageIDs.Contains(m.MessageID))
                        {
                            pop3.Messages[i].MarkForDeletion();
                        }
                    }
                }

                //与Pop3服务器断开连接
                pop3.Disconnect();
            }
        }
    }
}
